﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Text.RegularExpressions;

namespace DCS.Business.Model
{
    public class DCSFileGroup : List<DCSFile>
    {
        static log4net.ILog Logger = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
        static readonly System.IFormatProvider culture = new System.Globalization.CultureInfo("en-US", true);
        static readonly Regex rgPDate = new Regex("[0-9]{2}[A-Z]{3}[0-9]{2}");

        private string groupName = string.Empty;
        public string GroupName
        {
            get
            {
                if (this.Count == 0)
                {
                    return string.Empty;
                }

                if (groupName == string.Empty)
                {
                    groupName = this[0].RemoteFileName.Substring(0, this[0].RemoteFileName.IndexOf("_PART"));
                }
                return groupName;
            }
        }

        public string Carrier
        {
            get { return this.GroupName.Substring(0, 2); }
        }

        public string FlightNo
        {
            get { return this.GroupName.Substring(2, this.GroupName.IndexOf("_") - 2); }
        }

        public DateTime DeptDate
        {
            get
            {
                string pdate = rgPDate.Match(this.GroupName).Value;
                return DateTime.ParseExact(pdate, "ddMMMyy", culture);
            }
        }

        public string DeptAirport
        {
            get
            {
                Match m = new Regex("([A-Z0-9]+)_([A-Z0-9]+)_([A-Z]{3})([A-Z_]*)").Match(GroupName);
                //return this.GroupName.Substring(15, 4).Replace("_", string.Empty);
                return m.Groups[3].Value;
            }
        }

        public List<DCSFile> Order()
        {
            return this.OrderBy(d => d.PartNo).ToList();
        }

        /// <summary>
        /// Check if this is a Valid message group (ended, no lack) 
        /// </summary>
        public bool Validate
        {
            get
            {
                try
                {
                    int max = this.Max(d => d.PartNo);

                    for (int i = 1; i < max; i++)
                    {
                        if (!this.Exists(d => d.RemoteFileName == string.Format("{0}_PART{1}.txt", GroupName, i)))
                        {
                            if (this.First().CreateTime < DateTime.Now.AddHours(-6))
                            {
                                this.ForEach(a => a.Status = FileStatus.DownloadError);
                            }
                            else
                            {
                                this.ForEach(a => a.Status = FileStatus.FinishDownload);
                            }
                            return false;
                        }
                    }

                    DCSFile file = this.Find(d => d.RemoteFileName == string.Format("{0}_PART{1}.txt", GroupName, max));

                    //this method is the right way to check integrity, however it spend much more resurce...
                    using (FileStream fs = new FileStream(file.LocalPath + "\\" + file.LocalFileName, FileMode.Open))
                    {
                        using (StreamReader reader = new StreamReader(fs, Encoding.UTF8))
                        {
                            string text = reader.ReadToEnd();
                            if (text.IndexOf("END" + this.First().MessageType) == -1)
                            {
                                if (this.First().CreateTime < DateTime.Now.AddHours(-6))
                                {
                                    this.ForEach(a => a.Status = FileStatus.DownloadError);
                                }
                                else
                                {
                                    this.ForEach(a => a.Status = FileStatus.FinishDownload);
                                }
                                return false;
                            }
                        }
                    }
                }
                catch (Exception ex)
                {
                    Logger.ErrorFormat("ERROR DURING VALIDATE {0}-{1}-{2}", GroupName, ex.Message, ex.StackTrace);
                    this.ForEach(a => a.Status = FileStatus.Detected);
                    return false;
                }

                return true;
            }
        }
    }
}
